import hashlib
from google.appengine.ext import db
import logging
import Cookie
class User(db.Model):
  """This is the core User model for the application. This model holds
  the necessary information for logging in our user and also the 
  user profile customization. If there is not a required parameter 
  then the property is optional and will be set to empty as default.  """

  # Properties for logging in
  salt = db.StringProperty()
  hashed_password = db.StringProperty()
  email = db.StringProperty(required=True)
  
  # Properties for user customization
  importantMessages = db.ListProperty(int,required=True,default=None)
  readMessages = db.ListProperty(int,required=True,default=None)
  groups = db.ListProperty(int, default=None)
  firstTime = db.BooleanProperty(required=True,default=True)
  avatar = db.BlobProperty()
  displayname = db.StringProperty()
  aboutMe = db.StringProperty(default="",multiline=True)
  website = db.StringProperty(default="")
  moderator = db.BooleanProperty(default=False)
  super_user = db.BooleanProperty(default=False)
  
  
  # this is the temporary instance variable that holds the password until 
  # it is hash and salted on db entry. 
  password = str()
  
  def put(self):
    """Override the default put method to salt and hash our password before we 
    store it in the db."""
    
    # when the object is first created make sure that we create empty group list
    if self.firstTime:
      self.groups = list()
      
      # salt and hash the password when the user is first created.
      self.salt = "1h78f"
      self.hashed_password = hashlib.md5(self.password + self.salt).hexdigest()
    
    # make sure that every super_user is also a moderator
    if self.super_user:
      self.moderator = True

    # call the super method to actuall save in the db. 
    db.Model.put(self)
    

def authenticate(email=None, password=None):
  """This is a static function that can be called to perform the authentication
  of users. Simply pass in the attempted email address and password and the 
  function will return a user if the information is correct and matches or 
  None if the info is incorrect or a user can not be found."""

  # attempt to match a user in the db to the email provided
  query = User.all()
  query.filter("email = ", email)
  user = query.get()
  logging.info(user)
  
  # if the user is in the db the check that the password is correct.
  
  if user:
    attempted_password = hashlib.md5(password + user.salt).hexdigest()
    logging.info(attempted_password)
    logging.info(user.hashed_password)
    
    # if the password is correct return the user if not return None
    if user.hashed_password == attempted_password:
      return user
    else:
      return None

  # if there is no user in the db with the specified email return None
  else:
    return None
    
def get_current_user(request):
  """ Static function that is an attempt to mimic the google 
  user.get_current_user(). Function extracts the user_id from the 
  cookie and then queries the User table to find the user. If there is 
  no user found with that id then None is returned. Also if there is a 
  session value of -1 then it will return None. """
  
  cookie = Cookie.SimpleCookie()
  header = request.headers.get('Cookie')
  if header:
    cookie.load(header)
    
    # get the session id
    session_id = cookie["session_id"].value
    logging.info(session_id)
    
    # check to see if we have a -1 session value which means invalid
    if session_id == "-1":
      logging.info("inside for loop")
      return None
    user_id = cookie['user_id'].value
    user_id = int(user_id)
    return User.get_by_id(user_id)
  
